﻿using System;
using System.Collections.Generic;
using CarlosAg.ExcelXmlWriter;
using SdmxMl.Common;

namespace SdmxMl.Excel
{
    /// <summary> Base class for Excel export of Artefact </summary>
    public abstract class ExcelExportBase
    {
        #region Internal members

        protected Workbook book;
        protected Worksheet sheet;
        protected List<string> headerColArtefact;
        protected List<string> headerColitems;
        protected AnnotationInventory anInventory;

        #endregion

        #region C'tor

        public ExcelExportBase()
        {
            sheet = null;
            anInventory = new AnnotationInventory();
            headerColArtefact = new List<string>(16);

            headerColArtefact.Add("ID");
            headerColArtefact.Add("Agency");
            headerColArtefact.Add("Version");
            headerColArtefact.Add("Valid From");
            headerColArtefact.Add("Valid To");

            foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
                headerColArtefact.Add("Name_" + lg);

       //     foreach (string lg in SdmxMl.Common.LangSupport.arrLang)
       //         headerColArtefact.Add("Abbrev_" + lg);

            foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
                headerColArtefact.Add("Desc_" + lg);

        }
        #endregion

        #region Excel writing

        public void Save(string path)
        {
            if (book != null)
                book.Save(path);
        }
        #endregion

        #region Excel Book & Style objects generation

        protected void GenerateBook(string author, string company)
        {
            book = new Workbook();

            // -----------------------------------------------
            //  Properties
            // -----------------------------------------------
            book.Properties.Author = author;
            book.Properties.LastAuthor = author;
            book.Properties.Created = DateTime.Now;
            book.Properties.Company = company;
            book.Properties.Version = "11.9999";
            book.ExcelWorkbook.WindowHeight = 12270;
            book.ExcelWorkbook.WindowWidth = 15195;
            book.ExcelWorkbook.WindowTopX = 480;
            book.ExcelWorkbook.WindowTopY = 15;
            book.ExcelWorkbook.ActiveSheetIndex = 1;
            book.ExcelWorkbook.ProtectWindows = false;
            book.ExcelWorkbook.ProtectStructure = false;

            GenerateStyles();
        }

        protected virtual void GenerateStyles()
        {
            WorksheetStyleCollection styles = book.Styles;
            // -----------------------------------------------
            //  Default
            // -----------------------------------------------
            WorksheetStyle Default = styles.Add("Default");
            Default.Name = "Normal";
            Default.Alignment.Vertical = StyleVerticalAlignment.Bottom;
            // -----------------------------------------------
            //  s22 Header
            // -----------------------------------------------
            WorksheetStyle s22 = styles.Add("s22");
            s22.Font.FontName = "Arial Black";
            s22.Interior.Color = "#C0C0C0";
            s22.Interior.Pattern = StyleInteriorPattern.Solid;
            s22.Alignment.Vertical = StyleVerticalAlignment.Top;

            WorksheetStyle s23 = styles.Add("s23");
            s23.Alignment.WrapText = true;

        }
        #endregion

        #region Methods signature to be implemented in derived classes

        public virtual void Export()
        {
        }
        #endregion

        #region Excel sheet Artefact Attribute generation

        protected virtual void GenerateWorksheetArtefact(Artefact a)
        {
            sheet = book.Worksheets.Add("Artefact");
            sheet.Table.DefaultColumnWidth = 60F;
            sheet.Table.ExpandedColumnCount = 2 ;
            sheet.Table.ExpandedRowCount = headerColArtefact.Count;
            sheet.Table.FullColumns = 1;
            sheet.Table.FullRows = 1;
            // -----------------------------------------------

            WorksheetColumn columnData = sheet.Table.Columns.Add();
            columnData.Index = 2;
            columnData.Width = 266;
            columnData.StyleID = "s23";

            int row = 0;
            AddArtefactInfo(row++, a.Id);
            AddArtefactInfo(row++, a.AgencyId);
            AddArtefactInfo(row++, a.Version);
            AddArtefactInfo(row++, a.ValidFrom);
            AddArtefactInfo(row++, a.ValidTo);

            foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
                AddArtefactInfo(row++, a.Name.GetIfDefinedForLanguage(lg));

            foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
            {
                WorksheetRow wr = AddArtefactInfo(row++, a.Description.GetIfDefinedForLanguage(lg));
                wr.AutoFitHeight = true;
            }

            // Annotations
            foreach (Annotation ann in a.AnnotationList)
            {
                string annName = ann.Type;
                if (string.IsNullOrEmpty(ann.Title) == false)
                    annName += "_" + ann.Title;
                if (ann.Text.IsInternationalized)
                {
                    foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
                    {
                        string title = annName + "_" + lg;
                        WorksheetRow ws = sheet.Table.Rows.Add();
                        ++row;
                        ws.Cells.Add(title + ":", DataType.String, "s22");
                        ws.Cells.Add(ann.Text.GetForLanguage(lg));
                    }
                }
                else
                {
                    WorksheetRow ws = sheet.Table.Rows.Add();
                    ++row;
                    ws.Cells.Add(annName + ":", DataType.String, "s22");
                    ws.Cells.Add(ann.Text.GetFirst());
                }
            }
            // Update sheet count
            sheet.Table.ExpandedRowCount = 1 + row;

        }

        private WorksheetRow AddArtefactInfo(int rowIndex, string info)
        {
            WorksheetRow row = sheet.Table.Rows.Add();
          //  row.Height = 15;
            row.Cells.Add(headerColArtefact[rowIndex]+ ":", DataType.String, "s22");
            row.Cells.Add(info);
            return row;
        }
        #endregion

        #region Internal Helper methods

        protected virtual Worksheet GenerateWorksheetHeader(string[] headerColName, string sheetName, int rowCount)
        {
            Worksheet sheet = book.Worksheets.Add(sheetName);
            sheet.Table.DefaultColumnWidth = 80F;
            sheet.Table.ExpandedColumnCount = headerColName.Length; ;
            sheet.Table.ExpandedRowCount = 1 + rowCount;
            sheet.Table.FullColumns = 1;
            sheet.Table.FullRows = 1;
            // -----------------------------------------------
            WorksheetRow Row0 = sheet.Table.Rows.Add();
            Row0.Height = 15;
            foreach (string hc in headerColName)
                Row0.Cells.Add(hc, DataType.String, "s22");

            return sheet;
        }
        protected WorksheetCell AddCell(WorksheetRow row, string content)
        {
            return AddCell(row, content, string.Empty);
        }

        protected void AddAnnotations(WorksheetRow row, AnnotationList annotationList)
        {
            // For each annotation, 6 columns ANN_TYPE, ANN_TITLE, ALNN_TEXT_lg..
            foreach (KeyValuePair<string, AnnotationCount> kvp in anInventory.Dico)
            {
                for (int i = 0; i < kvp.Value.Count; i++)
                {
                    Annotation a = annotationList.GetAnnotationType(kvp.Value.Annot.Type, i + 1);
                    if (a != null)
                    {
                        if (kvp.Value.HasTitle)
                            AddCell(row, a.Title);

                        if (kvp.Value.Internationalized)
                        {
                            foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
                                AddCell(row, a.Text.GetIfDefinedForLanguage(lg));
                        }
                        else
                            AddCell(row, a.Text.GetFirst());

                        if (kvp.Value.HasUrn && a.Url != null)
                            AddCell(row, a.Url.ToString());
                    }
                    else
                    {
                        if (kvp.Value.HasTitle)
                            AddCell(row, string.Empty);

                        if (kvp.Value.Internationalized)
                        {
                        foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
                            AddCell(row, string.Empty);
                        }
                        else
                            AddCell(row, string.Empty);

                        if (kvp.Value.HasUrn)
                            AddCell(row, string.Empty);
                    }
                }
            }

        }

        protected WorksheetCell AddCell(WorksheetRow row, string content, string style)
        {
            WorksheetCell cell;
            cell = row.Cells.Add();
            cell.Data.Type = DataType.String;
            cell.Data.Text = content;
            if (style.Length > 0)
                cell.StyleID = style;
            return cell;
        }

        protected void ExportArtefact(Artefact a)
        {
        }
        #endregion
    }

}
